package com.stm.bi.report;

import com.stm.bi.core.util.DateUtils;
import com.stm.bi.dto.query.DeptChartQuery;
import com.stm.bi.dto.vo.SalesProIndexChartVO;
import com.stm.bi.model.Chart;
import com.stm.framework.core.context.UserHolder;
import com.stm.framework.core.util.FileResourceLoader;
import com.stm.framework.dbcp.JdbcService;
import com.stm.framework.dto.Response;
import com.stm.saas.api.ProductConfigRemoteService;
import com.stm.saas.dto.vo.ProductConfigVO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.*;

import static com.stm.bi.constant.PlanConstants.TYPE_DAY;
import static com.stm.bi.constant.IndexConstants.*;

/**
 * @author liuyx
 * @date 2025/2/13 10:14
 */
@Component
public class SalesProIndexChartQueryExe extends AbsChartQueryExe<DeptChartQuery, Chart<SalesProIndexChartVO>> {
    @Resource
    protected JdbcService jdbcService;

    @Resource
    protected ProductConfigRemoteService productConfigRemoteService;

    @Override
    public Chart<SalesProIndexChartVO> query(Long orgId, String orgNo, DeptChartQuery query) {
        LocalDate yesterDay = LocalDate.now().minusDays(1);
        LocalDate startDay = yesterDay.minusDays(29);

        Response<ProductConfigVO> prodResp = productConfigRemoteService.selectByOrgId(UserHolder.getOrgId());
        String salesDefinition = "dealing";
        if(prodResp != null && prodResp.getData() != null) {
            salesDefinition = prodResp.getData().getSalesDefinition();
        }
        if("delivery".equals(salesDefinition)) {
            salesDefinition = "dealing";
        }

        String selectSql = FileResourceLoader.getResourceAsString("/sql/adsBaseDefaultSales.sql");
        List<Map> maps = jdbcService.selectList(selectSql, new Object[]{
                orgId,
                query.getDeptId(),
                TYPE_DAY,
                salesDefinition,
                startDay,
                yesterDay});

        Chart chart = new Chart();
        chart.getItems().add("客数");
        chart.getItems().add("客单");
        List<String> dayList = DateUtils.getDateList(startDay.toString(), yesterDay.toString(), TYPE_DAY);

        chart.setDatas(getData(maps, dayList));
        chart.setExtend(getExtendSalesProIndexChartVO(maps, dayList));
        return chart;
    }

    private static List<List<Object>> getData(List<Map> maps, List<String> dayList) {
        List<List<Object>> data = new ArrayList<>();
        for (String date : dayList) {
            Map map = maps.stream()
                    .filter(m -> Objects.equals(m.get(DATE_FIELD), date))
                    .findAny().orElse(new HashMap());

            data.add(new ArrayList<>(Arrays.asList(
                    date,
                    map.get(NUMBER_OF_TRANSACTIONS_FIELD) == null ? BigDecimal.ZERO : map.get(NUMBER_OF_TRANSACTIONS_FIELD),
                    map.get(PER_CUSTOMER_TRANSACTION_FIELD) == null ? BigDecimal.ZERO : map.get(PER_CUSTOMER_TRANSACTION_FIELD))
            ));
        }
        return data;
    }

    private static SalesProIndexChartVO getExtendSalesProIndexChartVO(List<Map> maps, List<String> dayList) {
        double salesAmount = maps.stream()
                .map(m -> (BigDecimal) m.get(SALES_AMOUNT_FIELD))
                .filter(Objects::nonNull)
                .mapToDouble(BigDecimal::doubleValue)
                .sum();

        double numberOfTransactions = maps.stream()
                .map(m -> (BigDecimal) m.get(NUMBER_OF_TRANSACTIONS_FIELD))
                .filter(Objects::nonNull)
                .mapToDouble(BigDecimal::doubleValue)
                .sum();
        double perCustomerTransaction = 0;
        if (numberOfTransactions != 0) {
            perCustomerTransaction = salesAmount / numberOfTransactions;
        }
        SalesProIndexChartVO salesProIndexChartVO = new SalesProIndexChartVO();
        salesProIndexChartVO.setSales(BigDecimal.valueOf(salesAmount).setScale(2, RoundingMode.HALF_UP));
        salesProIndexChartVO.setPerNumberOfTransactions(BigDecimal.valueOf(numberOfTransactions / dayList.size()).setScale(2, RoundingMode.HALF_UP));
        salesProIndexChartVO.setPerCustomerTransaction(BigDecimal.valueOf(perCustomerTransaction).setScale(2, RoundingMode.HALF_UP));
        return salesProIndexChartVO;
    }

    @Override
    public String getReportName() {
        return "销售过程指标";
    }
}
